from datetime import datetime, timedelta
from typing import Optional
from jose import jwt, JWTError
import hashlib
import os
from app.core.config import settings

def get_password_hash(password: str) -> str:
    """获取密码哈希值
    使用 SHA256 + Salt 的方式进行密码哈希
    """
    # 生成随机salt
    salt = os.urandom(32)
    # 将密码和salt组合并计算哈希
    hash_obj = hashlib.sha256(salt + password.encode())
    # 返回 salt和hash的组合，使用:分隔，并进行base64编码
    return f"{salt.hex()}:{hash_obj.hexdigest()}"

def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    try:
        # 分离存储的salt和hash
        salt_hex, stored_hash = hashed_password.split(":")
        salt = bytes.fromhex(salt_hex)
        # 使用相同的salt计算输入密码的hash
        hash_obj = hashlib.sha256(salt + plain_password.encode())
        # 比较hash值
        return hash_obj.hexdigest() == stored_hash
    except Exception:
        return False

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
    """创建访问令牌"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(
            minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
        )
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(
        to_encode,
        settings.SECRET_KEY,
        algorithm=settings.ALGORITHM
    )
    return encoded_jwt

def decode_token(token: str) -> dict:
    """解码访问令牌"""
    try:
        decoded_token = jwt.decode(
            token,
            settings.SECRET_KEY,
            algorithms=[settings.ALGORITHM]
        )
        return decoded_token
    except jwt.ExpiredSignatureError:
        return None
    except jwt.JWTError:
        return None